#include "EventloopThread.h"
#include "Eventloop.h"
#include "thread/current_thread.h"
#include "utility/assertion.h"

EventloopThread::EventloopThread(const std::string &name): 
    EventloopThread(default_eventloop_thread_init_func, name) {}

EventloopThread::EventloopThread(
    EventloopThreadInitFunc initFunc, const std::string &name):
    _thread{[this](){ _func(); }, name},
    _cv{},
    _mutex{},
    _initFunc{std::move(initFunc)},
    _loop{} {}

EventloopThread::~EventloopThread() {
    stop();
}

void EventloopThread::start() {
    assert(!_thread.is_started());
    _thread.start();
    std::unique_lock lock{_mutex};
    _cv.wait(lock, [this](){ return _loop.has_value(); });
}

void EventloopThread::stop() {
    if (_loop.has_value()) {
        eventloop().quit();
    }
    if (_thread.is_started()) {
        _thread.join();
    }
}

void EventloopThread::_func() {
    Eventloop loop{};
    _initFunc(loop);
    {
        const std::lock_guard guard{_mutex};
        _loop = loop;
        _cv.notify_one();
    }
    loop.loop();
    _loop.reset();
}


